# frozen_string_literal: true

class DecisionTableService < ApplicationService
  class << self
    def show(id, page, size)
      dt = RuleEntity::DecisionTable.find(id)
      result = {
        decision_table: dt,
        header: dt.decision_table_headers,
        body: []
      }

      cells = dt.decision_table_rows

      page ||= 1
      size ||= 15
      cells = cells.where(ordinal: (page * size - size + 1)..(page * size))

      # value_headers = ['decision_table_rows.id', 'decision_table_rows.ordinal AS ordinal']
      # dt.decision_table_headers.each_with_index do |header, col_index|
      #   tb_name = header.name.gsub(/[^a-zA-Z0-9]/, '_').sub(/^/, 'dtc_')
      #   cells = cells.joins(
      #     "LEFT JOIN decision_table_cells AS #{tb_name}" \
      #       " ON decision_table_rows.id = #{tb_name}.decision_table_row_id" \
      #       " AND #{tb_name}.ordinal = #{col_index}"
      #   )
      #   value_headers << "#{tb_name}.value AS column_#{col_index}"
      # end
      # result.merge body: cells.select(value_headers).as_json

      result.merge body: build_cells_from_rows(dt.decision_table_headers, cells)
    end

    def build_cells_from_rows(headers, rows)
      value_headers = ['decision_table_rows.id', 'decision_table_rows.ordinal AS ordinal']

      headers.includes(schema_variable: :variable_type)
      headers.ordinal_asc.each_with_index do |header, col_index|
        tb_name = header.name.gsub(/[^a-zA-Z0-9]/, '_').sub(/^/, 'dtc_')
        rows = rows.joins(
          "LEFT JOIN decision_table_cells AS #{tb_name}" \
            " ON decision_table_rows.id = #{tb_name}.decision_table_row_id" \
            " AND #{tb_name}.ordinal = #{col_index}"
        )

        value_headers << "#{tb_name}.#{dt_column_name_by_header(header)} AS column_#{col_index}"
      end

      rows.select(value_headers).as_json
    end

    def dt_column_name_by_header(header)
      DecisionTableCell.dt_column_name(header.schema_variable.variable_type.name)
    end
  end
end
